package network

import (
	"log"
	"net"
	"time"
)

type netConnector struct {
	conn          net.Conn
	autoReConnSes int
	working       bool
	EventQueue
	*sesMgr
}

func (self *netConnector) Start(addr string) Peer {
	if self.working {
		return self
	}

	go self.connect(addr)

	return self
}

func (self *netConnector) connect(addr string) {
	self.working = true

	for {
		cn, err := net.Dial("tcp", addr)
		if nil != err {
			log.Printf("#connect failed(%s) %v", addr, err.Error())
			if 0 < self.autoReConnSes {
				//reconn
				time.Sleep(time.Duration(self.autoReConnSes) * time.Second)

				continue
			}
			break
		}

		self.conn = cn

		ses := newSession(NewStream(cn), self.EventQueue, self)
		log.Println("#connected ", addr)

		self.sesMgr.Add(ses)
		ses.OnClose = func() {
			//
		}

		self.PostData(NewSesEvent(E_SES_CONNECTED, ses, nil))

		return
	}
	self.working = false
}

func (self *netConnector) Stop() {
	if nil != self.conn {
		self.conn.Close()
	}
}

func (self *netConnector) SetAutoReConn(sec int) {
	self.autoReConnSes = sec
}

func NewConnector(pipe EventPipe) Peer {
	self := &netConnector{
		EventQueue:    pipe.AddQueue(),
		autoReConnSes: 3,
		sesMgr:        NewSesManager(),
	}

	return self
}
